home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / GNU-SMALLTALK.lha / Rectangle.st < prev    next >
Text File  |  1992-02-15  |  12KB  |  383 lines

  1. "========================================================================
  2. |
  3. |   Rectangle Class
  4. |
  5.  ========================================================================"
  6.  
  7. "======================================================================
  8. |
  9. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  10. | Written by Steve Byrne.
  11. |
  12. | This file is part of GNU Smalltalk.
  13. |
  14. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  15. | under the terms of the GNU General Public License as published by the Free
  16. | Software Foundation; either version 1, or (at your option) any later version.
  17. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  18. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  19. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  20. | details.
  21. | You should have received a copy of the GNU General Public License along with
  22. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  23. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  24. |
  25.  ======================================================================"
  26.  
  27.  
  28. "
  29. |     Change Log
  30. | ============================================================================
  31. | Author       Date       Change
  32. | sbb         10 Jul 91      Altered the printing and storing to use cascaded
  33. |              messages.
  34. |
  35. | sbb         10 Jul 91      Added #= and #hash methods.
  36. |
  37. | dougm      19 Apr 90    Initial definitions for Rectangle class (needs Point)
  38. |
  39. "
  40.  
  41. Object subclass: #Rectangle
  42.        instanceVariableNames: 'origin corner'
  43.        classVariableNames: ''
  44.        poolDictionaries: ''
  45.        category: nil
  46. !
  47.  
  48. Rectangle comment:
  49. 'Beginning of the Rectangle class for simple display manipulation.
  50.  Rectangles require the Point class to be available.  An extension
  51.  to the Point class is made here that since it requires Rectangles
  52.  to be defined (see converting)' !
  53.  
  54. !Rectangle class methodsFor: 'instance creation'!
  55.  
  56. origin: originPoint corner: cornerPoint
  57.     ^self new origin: originPoint corner: cornerPoint
  58. !
  59.  
  60. origin: originPoint extent: extentPoint
  61.     ^self new origin: originPoint corner: (originPoint + extentPoint)
  62. !
  63.  
  64. left: leftNumber right: rightNumber top: topNumber bottom: bottomNumber
  65.     ^self new origin: (Point x: leftNumber y: topNumber) corner: (Point x: rightNumber y: bottomNumber)
  66. !!
  67.  
  68. !Rectangle methodsFor: 'accessing'!
  69.  
  70. origin: originPoint corner: cornerPoint
  71.     origin _ originPoint.
  72.     corner _ cornerPoint
  73. !
  74.  
  75. origin
  76.     ^origin
  77. !
  78.  
  79. corner
  80.     ^corner
  81. !
  82.  
  83. topLeft
  84.     ^origin
  85. !
  86.  
  87. topCenter
  88.     ^Point x: (origin x + (self width / 2)) y: (origin y)
  89. !
  90.  
  91. topRight
  92.     ^Point x: (corner x) y: (origin y)
  93. !
  94.  
  95. rightCenter
  96.     ^Point x: (corner x) y: (origin y + (self height / 2))
  97. !
  98.  
  99. bottomCenter
  100.     ^Point x: (origin x + (self width / 2)) y: (corner y)
  101. !
  102.  
  103. bottomLeft
  104.     ^Point x: (origin x) y: (corner y)
  105. !
  106.  
  107. bottomRight
  108.     ^corner
  109. !
  110.  
  111. leftCenter
  112.     ^Point x: (origin x) y: (origin y + (self height / 2))
  113. !
  114.  
  115. center
  116.     ^Point x: (origin x + (self width / 2))
  117.        y: (origin y + (self height / 2))
  118. !
  119.  
  120. area
  121.     ^ (self width) * (self height)
  122. !
  123.  
  124. width
  125.     ^(corner x) - (origin x)
  126. !
  127.  
  128. height
  129.     ^(corner y) - (origin y)
  130. !
  131.  
  132. extent
  133.     ^Point x: (self width) y: (self height)
  134. !
  135.  
  136. top
  137.     ^(origin y)
  138. !
  139.  
  140. right
  141.     ^(corner x)
  142. !
  143.  
  144. bottom
  145.     ^(corner y)
  146. !
  147.  
  148. left
  149.     ^(origin x)
  150. !!
  151.  
  152.  
  153. "Not yet implemented: messages to set the locations as mentioned on p 346"
  154.  
  155.  
  156.  
  157. !Rectangle methodsFor: 'testing'!
  158.  
  159. containsPoint: aPoint
  160.     ^(origin < aPoint) & (corner > aPoint)
  161. !
  162.  
  163. contains: aRectangle
  164.     ^(self containsPoint: (aRectangle origin)) &
  165.        (self containsPoint: (aRectangle corner))
  166. !
  167.  
  168. intersects: aRectangle
  169.     ^(self containsPoint: aRectangle topLeft) or:
  170.        [(self containsPoint: aRectangle topRight) or:
  171.            [(self containsPoint: aRectangle bottomLeft) or:
  172.                [(self containsPoint: aRectangle bottomRight)]]]
  173. !
  174.  
  175. = aRectangle
  176.     ^(origin = aRectangle origin)
  177.     and: [ corner = aRectangle corner ]
  178. !
  179.  
  180. hash
  181.     ^(origin hash) * (corner hash)
  182. !!
  183.  
  184. !Rectangle methodsFor: 'rectangle functions'!
  185.  
  186. amountToTranslateWithin: aRectangle
  187.     ^(aRectangle origin)-origin
  188. !
  189.  
  190. "----------------------------------------------------------------
  191. |areasOutside: aRectangle
  192. | most complicated of the Rectangle primitives
  193. | The basic methodology is to first determine that there is an
  194. | intersection by finding the overlapping rectangle.  From the
  195. | overlapping rectangle, first determine if it runs along an edge.
  196. | If it doesn't, extend the rectangle up to the top edge and add
  197. | the new rectangle to the collection and start the rest of the
  198. | process.  If the left edge does not touch the left edge of self,
  199. | extend it to the edge saving the new rectangle.  Then do the
  200. | same to the right edge.  Then check top and bottom edges.  Most
  201. | of the time only 2 or 3 rectangles get formed, occasionally 4.
  202. | It should be possible to never get more than 3 but requires more
  203. | work.
  204.  ----------------------------------------------------------------"
  205.  
  206. areasOutside: aRectangle
  207.     | collect iRect tmp |
  208.     iRect _ self intersect: aRectangle.
  209.     (iRect = nil) ifTrue: [^nil]. "case of no intersection"
  210.                                "the collect collection gathers Rectangles"
  211.     collect _ OrderedCollection new: 4.
  212.                                "is it floating or on the edge?"
  213.     (((iRect top) ~= self top) &
  214.              ((iRect bottom) ~= self bottom) &
  215.                    ((iRect left) ~= self left) & ((iRect right) ~= self right))
  216.        ifTrue: "entirely in the center."
  217.            [tmp _ Rectangle origin: (Point x: iRect left y: self top)
  218.                             corner: iRect bottomRight.
  219.             collect add: tmp.
  220.             iRect _ iRect merge: tmp].
  221.     ((iRect left) ~= self left)
  222.        ifTrue:                 "doesn't touch left edge so make it touch"
  223.            [tmp _ Rectangle origin: (Point x: self left y: iRect top)
  224.                                 corner: iRect bottomLeft.
  225.                 collect add: tmp.
  226.                                "merge new (tmp) with overlap to keep track"
  227.                 iRect _ iRect merge: tmp].
  228.     ((iRect right) ~= self right)
  229.        ifTrue:                 "doesn't touch right edge so extendi it"
  230.            [tmp _ Rectangle origin: iRect topRight
  231.                                 corner: (Point x: self right y: iRect bottom).
  232.                 collect add: tmp.
  233.                 iRect _ iRect merge: tmp].
  234.     (((iRect left) ~= self left) | ((iRect top) ~= self top))
  235.        ifTrue:                 "whole top part can be taken now"
  236.            [tmp _ Rectangle origin: origin corner: iRect topRight.
  237.                 collect add: tmp].
  238.     (((iRect right) ~= self right) | ((iRect bottom) ~= self bottom))
  239.        ifTrue:                 "whole bottom open and can be taken"
  240.            [tmp _ Rectangle origin: iRect bottomLeft corner: corner.
  241.                 collect add: tmp].
  242.     ^collect
  243. !
  244.  
  245. expandBy: delta
  246.     delta _ delta asRectangle.    "not completed"
  247.     (delta isMemberOf: Point) ifTrue:
  248.        [^Rectangle origin: (origin-delta)
  249.                    corner: (corner+delta)].
  250.     (delta isMemberOf: Rectangle) ifTrue:
  251.        [^Rectangle origin: (origin-(delta origin))
  252.                    corner: (corner+(delta corner))].
  253.     (delta isKindOf: Number) ifTrue:
  254.        [^Rectangle left: (origin x)-delta
  255.                    right:(corner x)+delta
  256.                    top:  (origin y)-delta
  257.                    bottom:(corner y)+delta].
  258.     self error: 'Illegal delta value'
  259. !
  260.  
  261. insetBy: delta
  262.     (delta isMemberOf: Point) ifTrue:
  263.        [^Rectangle origin: (origin+delta)
  264.                    corner: (corner-delta)].
  265.     (delta isMemberOf: Rectangle) ifTrue:
  266.        [^Rectangle origin: (origin+(delta origin))
  267.                    corner: (corner-(delta corner))].
  268.     (delta isKindOf: Number) ifTrue:
  269.        [^Rectangle left: (origin x)+delta
  270.                    right:(corner x)-delta
  271.                    top:  (origin y)+delta
  272.                    bottom:(corner y)-delta].
  273.     self error: 'Illegal delta value'
  274. !
  275.  
  276. insetOriginBy: originDeltaPoint corner: cornerDeltaPoint
  277.     ^Rectangle origin: origin + originDeltaPoint
  278.               corner: corner + cornerDeltaPoint
  279. !
  280.  
  281. merge: aRectangle
  282.     | orig corn |
  283.     orig _ Point x: ((origin x) min: (aRectangle origin x))
  284.                 y: ((origin y) min: (aRectangle origin y)).
  285.     corn _ Point x: ((corner x) max: (aRectangle corner x))
  286.                 y: ((corner y) max: (aRectangle corner y)).
  287.     ^Rectangle origin: orig corner: corn
  288. !
  289.  
  290. "--------------------------------------------------------------
  291. | A intersect: B
  292. |   returns the rectangle (if any) created by the overlap of
  293. |   rectangles A and B.  There are 10 possible overlap situations:
  294. |      A inside B
  295. |      B inside A
  296. |      A overlaps B at one of the four corners (1 point inside)
  297. |      A overlaps B on one of the four sides (2 points inside)
  298.  ---------------------------------------------------------------"
  299.  
  300. intersect: aRectangle
  301.     (self contains: aRectangle) ifTrue: [^Rectangle origin: aRectangle origin
  302.                                                    corner: aRectangle corner].
  303.     (aRectangle contains: self)  ifTrue: [^Rectangle origin: origin
  304.                                                     corner: corner].
  305.     (self containsPoint: aRectangle topLeft)
  306.        ifTrue: [ (self containsPoint: aRectangle topRight)
  307.                      ifTrue: [^Rectangle origin: aRectangle origin
  308.                                          corner: (Point x: aRectangle corner x
  309.                                                        y: corner y)]
  310.                      ifFalse: [^Rectangle origin: aRectangle origin
  311.                                           corner: corner]].
  312.     (self containsPoint: aRectangle topRight)
  313.        ifTrue: [^Rectangle origin: (Point x: origin x y: aRectangle origin y)
  314.                            corner: (Point x: aRectangle corner x y: corner y)].
  315.     (self containsPoint: aRectangle bottomLeft)
  316.        ifTrue: [ (self containsPoint: aRectangle bottomRight)
  317.                      ifTrue: [^Rectangle origin: (Point x: aRectangle origin x
  318.                                                         y: origin y)
  319.                                          corner: aRectangle corner]
  320.                      ifFalse: [^Rectangle origin: (Point x: aRectangle origin x
  321.                                                          y: origin y)
  322.                                           corner: aRectangle corner]].
  323.     (self containsPoint: aRectangle bottomRight)
  324.        ifTrue: [^Rectangle origin: origin corner: aRectangle corner]
  325.        ifFalse: [^nil]
  326. !!
  327.  
  328. !Rectangle methodsFor: 'printing'!
  329.  
  330. printOn: aStream
  331.     aStream print: origin;
  332.     nextPutAll: ' corner: ';
  333.     print: corner
  334. !
  335.  
  336. storeOn: aStream
  337.     aStream nextPutAll: '(Rectangle origin: ';
  338.     store: origin;
  339.     nextPutAll: ' corner: ';
  340.     store: corner;
  341.     nextPut: $)
  342. !!
  343.  
  344. !Rectangle methodsFor: 'truncation and round off'!
  345.  
  346. rounded
  347.     ^Rectangle origin: origin rounded corner: corner rounded
  348. !!
  349.  
  350. !Rectangle methodsFor: 'transforming'!
  351.  
  352. moveBy: aPoint
  353.     origin _ origin + aPoint.
  354.     corner _ corner + aPoint
  355. !
  356.  
  357. moveTo: aPoint
  358.     | diff |
  359.     diff _ aPoint - origin.
  360.     origin _ aPoint.
  361.     corner _ corner + diff
  362. !
  363.  
  364. scaleBy: scale
  365.     ^Rectangle origin: origin * scale corner: corner * scale
  366. !
  367.  
  368. translateBy: factor
  369.     ^Rectangle origin: origin + factor corner: corner + factor
  370. !!
  371.  
  372. !Point methodsFor: 'converting'!
  373.  
  374. corner: aPoint
  375.     ^Rectangle origin: self corner: aPoint
  376. !
  377.  
  378. extent: aPoint
  379.     ^Rectangle origin: self extent: aPoint
  380. !!
  381.